import axios from 'axios'
import store from '@/store'
import router from '../router'
import Vue from 'vue'
import qs from 'qs'
const vueInstance = new Vue()
const request = axios.create({
  // 配置选项
  // baseURL,
  baseURL:
    process.env.NODE_ENV === 'development' ? '' : 'http://139.155.233.245'
  // timeout
})

/**
 * @description 跳转到登录
 */
const redirectLogin = () => {
  router.push({
    name: 'login',
    query: {
      redirect: router.currentRoute.fullPath
    }
  })
}

const refreshToken = () => {
  return axios.create().post(
    '/front/user/refresh_token',
    qs.stringify({
      refreshtoken: store.state.user.refresh_token
    })
  )
}
let isRefreshing = false // 控制刷新token的状态
let requestQueue: any[] = [] // 收集失败的请求
// 请求拦截器
request.interceptors.request.use(
  config => {
    const user = store.state.user
    // 有些登录接口带了token反而有问题，所以排除登录接口
    if (user && user.access_token && config.url !== '/front/user/login') {
      config.headers.Authorization = user.access_token
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  async resp => {
    // 请求收到相应，但是状态在2xx内
    // console.log(resp)
    return resp
  },
  async error => {
    console.dir(error)
    if (error.response) {
      const { status } = error.response
      if (status === 400) {
        vueInstance.$message({
          showClose: true,
          message: '请求参数错误',
          type: 'error'
        })
      } else if (status === 401) {
        if (!store.state.user) {
          // 未登录
          redirectLogin()
          return Promise.reject(error)
        }
        // 新的axios实例去刷新token,避免死循环
        if (!isRefreshing) {
          // 没有其它请求在刷新
          try {
            // add lock
            isRefreshing = true
            const res = await refreshToken()
            if (!res.data.success) {
              throw new Error('刷新token失败')
            }
            // 重新设置token
            store.commit('setUser', res.data.content)
            // 重新发送失败的请求
            // console.log(error.config)
            // 执行队列的失败请求
            requestQueue.forEach(ele => {
              ele()
            })

            return request(error.config)
          } catch (error) {
            // 清除原始token
            store.commit('setUser', null)
            // console.log(error)
            redirectLogin()
            return Promise.reject(error)
          } finally {
            isRefreshing = false
            // 清空队列
            requestQueue = [] // 个人认为该放这里
          }
        } else {
          return new Promise(resolve => {
            requestQueue.push(() => {
              resolve(request(error.config))
            })
          })
        }
      } else if (status === 403) {
        vueInstance.$message({
          showClose: true,
          message: '没有权限，请联系管理员',
          type: 'error'
        })
      } else if (status === 404) {
        vueInstance.$message({
          showClose: true,
          message: '请求资源不存在',
          type: 'error'
        })
      } else if (status >= 500) {
        vueInstance.$message({
          showClose: true,
          message: '服务器异常，请联系管理员',
          type: 'error'
        })
      }
      // 请求收到响应，但是状态超出2xx
    } else if (error.request) {
      // 没有收到响应，如网络超时
      vueInstance.$message({
        showClose: true,
        message: '请求超时，请刷新重试',
        type: 'error'
      })
    } else {
      // 设置请求时发生了错误
      vueInstance.$message({
        showClose: true,
        message: `请求失败:${error.message}`,
        type: 'error'
      })
    }

    return Promise.reject(error)
  }
)
export default request
